﻿using AutoMapper;
using System;
using System.Linq;

namespace Ideaa.Core.Extensions
{
    public static class AutoMapperExtensions
    {
        /// <summary>
        /// Ignores all virtual members of destination
        /// </summary>
        public static IMappingExpression<TSource, TDestination>
               IgnoreAllVirtual<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
        {
            var destinationType = typeof(TDestination);

            var virtualProperties = destinationType
                .GetProperties()
                .Where(prop => prop.GetGetMethod().IsVirtual);

            foreach (var property in virtualProperties)
            {
                expression.ForMember(property.Name, opt => opt.Ignore());
            }

            return expression;
        }

        /// <summary>
        /// Applies mapping to members that are derived from the base class and are not already mapped
        /// </summary>
        public static IMappingExpression<TSource, TDestination>
            InheritMappingFromBaseType<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
        {
            var sourceType = typeof(TSource);
            var desctinationType = typeof(TDestination);
            var sourceParentType = sourceType.BaseType;
            var destinationParentType = desctinationType.BaseType;

            expression
                .ForAllMembers(x => x.Condition(r => NotAlreadyMapped(sourceParentType, destinationParentType, r)));

            return expression;
        }

        private static bool NotAlreadyMapped(Type sourceType, Type desitnationType, ResolutionContext r)
        {
            return !r.IsSourceValueNull &&
                   Mapper.FindTypeMapFor(sourceType, desitnationType).GetPropertyMaps().Where(
                       m => m.DestinationProperty.Name.Equals(r.MemberName)).Select(y => !y.IsMapped()).All(b => b);
        }
        
    }
}
